<?php
class flexmenu {
  public static $types;
  
  public static $params;
  
  public static $stack = array ();
  
  public static $connection = array ();
  
  public static $m_settings = array ();
  
  function stack($link = FALSE) {
    
    //TODO: need to cache everything here, because menu call on all page and if have not cache, it make site slow
    if ($link) {
      $menu_name = $link ['menu_name'];
      $mlid = $link ['mlid'];
      $plid = $link ['plid'];
      
      if ($plid > 0) {
        //unset colums parameter of parent id(plid) if end of colums
        if (isset ( self::$connection ['cols'] [$plid] ['end'] ) && self::$connection ['cols'] [$plid] ['end']) {
          unset ( self::$connection ['cols'] [$plid] );
        }
        
        if (! isset ( self::$connection ['cols'] [$plid] )) {
          if (isset ( self::$params [$menu_name] [$plid] )) {
            $settings = unserialize ( self::$params [$menu_name] [$link ['plid']]->settings );
            
            if ($settings ['column'] > 1) {
              $cols = array ();
              $cols ['n_col'] = $settings ['column'];
              $cols ['c_col'] = 1;
              $cols ['c_item'] = 1;
              $cols ['total'] = self::$params [$menu_name] [$link ['plid']]->nchild;
              
              $cols ['index'] = 1;
              $cols ['begin'] = TRUE;
              $cols ['first'] = TRUE;
              //calculate number item of colums
              $n_item = floor ( $cols ['total'] / $cols ['n_col'] );
              
              $cols ['r'] = $cols ['total'] % $cols ['n_col'];
              if ($cols ['r'])
                $n_item = $n_item + 1;
              $cols ['n_item'] = $n_item;
              
              if ($n_item == 1) {
                $cols ['last'] = TRUE;
              } else {
                $cols ['last'] = false;
              }
              
              if ($cols ['total'] > 1) {
                $cols ['end'] = FALSE;
              } else {
                $cols ['end'] = TRUE;
              }
              
              self::$connection ['cols'] [$plid] = $cols;
            }
          }
        } else {
          $cols = & self::$connection ['cols'] [$plid];
          $cols ['c_item'] ++;
          
          //if before it in last item of col, now will become first
          if ($cols ['last']) {
            $cols ['first'] = true;
            $cols ['c_col'] ++;
          } else {
            $cols ['first'] = false;
          }
          
          //will check last and first just base on c_item and c_col
          $r = $cols ['c_item'] % $cols ['n_item'];
          
          $c = floor ( $cols ['c_item'] / $cols ['n_item'] );
          
          $cols ['last'] = false;
          if ($r == 0) {
            $cols ['last'] = true;
          } else {
            if ($c >= $cols ['r'] && $cols ['r'] > 0) {
              if (($cols ['c_item'] - $cols ['r'] * $cols ['n_item']) % ($cols ['n_item'] - 1) == 0) {
                $cols ['last'] = true;
              }
            }
          }
          
          if ($cols ['c_item'] == $cols ['total']) {
            $cols ['end'] = true;
            $cols ['last'] = true;
          }
          
          if ($cols ['first']) {
            $cols ['index'] = 1;
          } else if ($cols ['last']) {
            $cols ['index'] = - 1;
          } else {
            $cols ['index'] ++;
          }
        }
      }
      
      array_push ( self::$stack, $link );
      return $link;
    } else {
      $link = array_pop ( self::$stack );
      
      self::$connection ['link'] = $link;
      return $link;
    }
  }
  
  function load($reload = TRUE) {
    $cache = cache_get ( 'flexmenu', 'cache_menu' );
    
    if (! isset ( $cache->data ) || $reload) {
      //first load type of menu list
      $query = "SElECT * FROM {fm_menu}";
      $types = array ();
      $m_settings = array ();
      $result = db_query ( $query );
      while ( $row = db_fetch_object ( $result ) ) {
        $types [$row->menu_name] = $row->type;
        $m_settings [$row->menu_name] = unserialize ( $row->settings );
      }
      
      //assign types for global variable
      self::$types = $types;
      self::$m_settings = $m_settings;
      
      $query = "SELECT fm.type, fm.settings as m_settings, fmi.*, count(ml.mlid) nchild
             FROM {fm_menu} fm INNER JOIN {fm_menu_item} fmi ON fm.menu_name = fmi.menu_name
             LEFT JOIN {menu_links} ml ON fmi.mlid = ml.plid
             WHERE (ml.hidden != -1 OR ml.hidden is NULL)
             GROUP BY fmi.mlid
           ";
      
      $result = db_query ( $query );
      
      $params = array ();
      while ( $row = db_fetch_object ( $result ) ) {
        if (! isset ( $params [$row->menu_name] )) {
          $params [$row->menu_name] = array ();
        }
        
        $params [$row->menu_name] [$row->mlid] = $row;
      }
      
      
      $cache = array ();
      $cache ['types'] = $types;
      $cache ['params'] = $params;
      $cache ['m_settings'] = $m_settings;
      
      cache_set ( 'flexmenu', $cache, 'cache_menu' );
      
      self::$params = $params;
      
      return;
    }
    
    $data = $cache->data;
    
    self::$types = $data ['types'];
    self::$params = $data ['params'];
    self::$m_settings = $data ['m_settings'];
  }
}